package com.liruo.idworker.distributed.twitter;

import com.liruo.idworker.distributed.twitter.strategy.MachineIDStrategy;
import com.liruo.idworker.exception.OutOfRangeException;
import com.liruo.treasureattic.common.util.BitUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author:liruo
 * @Date:2023-02-06-19:54:57
 * @Desc
 */
@Slf4j
public class DefaultMachineIdStrategy extends AbstractMachineIdStrategy {
    public DefaultMachineIdStrategy(int dataCenterId, int machineId) {
        super(dataCenterId, machineId);
    }
    /**
     * 到11位的dataCenterId和不动的inCenterMachineId
     */
    @Override
    protected int assemblyMachineID() {
        int dataCenterBits = BitUtils.findHigh1(this.dataCenterId);
        int inCenterMachineIdBits = BitUtils.findHigh1(this.inCenterMachineId);
        int machineIdBits = dataCenterBits + inCenterMachineIdBits + 2;
        if(machineIdBits > MachineIDStrategy.MAX_MACHINE_ID_BITS){
            throw new OutOfRangeException(
                    "dataCenterId[%d] and inCenterMachineId[%d] totalBits[%d] out of machineIdBits[%d], diff=%d".formatted(
                            this.dataCenterId,this.inCenterMachineId,
                            machineIdBits,
                            MachineIDStrategy.MAX_MACHINE_ID_BITS,
                            MachineIDStrategy.MAX_MACHINE_ID_BITS - machineIdBits
                    )
            );
        }
        int machineId = 0;
        machineId |= BitUtils.rmToTarget(this.dataCenterId, 11, dataCenterBits);
        machineId |= this.inCenterMachineId;
        if(log.isDebugEnabled()){
            log.debug("machineId={}\ndataCenterId[{}=={}]to leftmost\ninCenterMachineId[{}=={}]to right most",
                    Integer.toBinaryString(machineId),
                    this.dataCenterId, Integer.toBinaryString(this.dataCenterId),
                    this.inCenterMachineId, Integer.toBinaryString(this.inCenterMachineId)
            );
        }
        return machineId;
    }
}
